/**
 * 视频数据模型
 * @author HalRui
 * @version 1.0.0
 * @description 基于Mongoose的视频数据模型，定义视频数据结构、验证规则和操作方法
 * @date 2025年9月27日
 */

const mongoose = require('mongoose');

// 自增 ID 计数器模型，用于生成自动增长的视频ID
const VideoIdCounterSchema = new mongoose.Schema({
    _id: { type: String, required: true }, // 如 'videoId'
    sequence_value: { type: Number, default: 0 }
});

const VideoIdCounter = mongoose.model('VideoIdCounter', VideoIdCounterSchema);

// 视频 Schema
const videoSchema = new mongoose.Schema({
    videoID: {
        type: Number,
        unique: true,
        index: true,
        description: "全局唯一自增视频ID"
    },
    fromID: {
        type: String,
        required: true,
        index: true,
        description: "发布者用户ID"
    },
    isDuet: {
        type: Boolean,
        default: false,
        description: "是否为合拍视频"
    },
    publishTime: {
        type: Date,
        default: Date.now,
        description: "视频发布时间"
    },
    title: {
        type: String,
        required: true,
        maxlength: 100,
        description: "视频标题"
    },
    content: {
        type: String,
        maxlength: 500,
        description: "视频文案/描述"
    },
    path: {
        type: String,
        required: true,
        description: "视频文件存储路径（私有）"
    },
    videoType: {
        type: String,
        enum: ['shortVideo', 'theater', 'shortDrama', 'live'],
        default: 'shortVideo',
        description: "视频类型"
    },
    isPrivate: {
        type: Boolean,
        default: false,
        description: "是否私密（仅自己可见）"
    },
    isFeatured: {
        type: Boolean,
        default: false,
        description: "是否为精选推荐"
    },
    viewCount: {
        type: Number,
        default: 0,
        min: 0,
        description: "浏览次数"
    },
    likeCount: {
        type: Number,
        default: 0,
        min: 0,
        description: "点赞次数"
    },
    shareCount: {
        type: Number,
        default: 0,
        min: 0,
        description: "转发/分享次数"
    },
    collectCount: {
        type: Number,
        default: 0,
        min: 0,
        description: "收藏次数"
    },
    comments: [{
        userId: {
            type: String,
            required: true
        },
        content: {
            type: String,
            required: true,
            maxlength: 500
        },
        createdAt: {
            type: Date,
            default: Date.now
        }
    }],
    createdAt: {
        type: Date,
        default: Date.now,
        description: "文档创建时间"
    },
    updatedAt: {
        type: Date,
        default: Date.now,
        description: "最后更新时间"
    }
}, {
    versionKey: false // 禁用 __v
});

// 保存前中间件：生成 videoID & 更新时间
videoSchema.pre('save', async function(next) {
    if (this.isNew && !this.videoID) {
        try {
            const counter = await VideoIdCounter.findByIdAndUpdate(
                'videoId',
                { $inc: { sequence_value: 1 } },
                { new: true, upsert: true, setDefaultsOnInsert: true }
            );
            this.videoID = counter.sequence_value;
        } catch (error) {
            return next(error);
        }
    }
    this.updatedAt = new Date();
    next();
});

// === 静态方法 ===

/**
 * 创建视频（带错误处理）
 * @param {Object} videoData
 * @returns {Object} { success, video, error }
 */
videoSchema.statics.createVideo = async function(videoData) {
    try {
        const video = new this(videoData);
        await video.save();
        return { success: true, video };
    } catch (error) {
        console.error('[VideoModel] 创建视频失败:', error);
        return {
            success: false,
            error: error.message,
            code: error.name === 'ValidationError' ? 'VALIDATION_ERROR' : 'DB_ERROR'
        };
    }
};

/**
 * 根据发布者ID查询视频（支持分页和排序）
 * @param {string} fromID
 * @param {number} page - 页码（从1开始）
 * @param {number} limit - 每页数量
 * @returns {Promise<Object>} 包含分页信息的结果
 */
videoSchema.statics.findByFromID = async function(fromID, page = 1, limit = 10) {
    const skip = (page - 1) * limit;
    const [videos, total] = await Promise.all([
        this.find({ fromID })
            .sort({ publishTime: -1 })
            .skip(skip)
            .limit(limit)
            .select('-path -ip') // 默认不返回敏感字段
            .lean(), // 返回普通对象，提高性能
        this.countDocuments({ fromID })
    ]);

    return {
        videos,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit),
            hasMore: skip + videos.length < total
        }
    };
};

// === 统计类更新方法 ===

// 增加浏览数
videoSchema.statics.increaseViewCount = async function(videoID) {
    return await this.findOneAndUpdate(
        { videoID },
        { $inc: { viewCount: 1 }, updatedAt: new Date() },
        { new: true, fields: { path: 0, ip: 0 } } // 不返回 path
    );
};

// 增加点赞
videoSchema.statics.increaseLikeCount = async function(videoID) {
    return await this.findOneAndUpdate(
        { videoID },
        { $inc: { likeCount: 1 }, updatedAt: new Date() },
        { new: true }
    );
};

// 增加转发
videoSchema.statics.increaseShareCount = async function(videoID) {
    return await this.findOneAndUpdate(
        { videoID },
        { $inc: { shareCount: 1 }, updatedAt: new Date() },
        { new: true }
    );
};

// 增加收藏
videoSchema.statics.increaseCollectCount = async function(videoID) {
    return await this.findOneAndUpdate(
        { videoID },
        { $inc: { collectCount: 1 }, updatedAt: new Date() },
        { new: true }
    );
};

// 添加评论
videoSchema.statics.addComment = async function(videoID, userId, content) {
    return await this.findOneAndUpdate(
        { videoID },
        {
            $push: {
                comments: {
                    userId,
                    content,
                    createdAt: new Date()
                }
            },
            updatedAt: new Date()
        },
        { new: true }
    );
};

// === 实例方法 ===

/**
 * 获取安全的JSON对象（用于API响应）
 * @returns {Object} 脱敏后的视频数据
 */
videoSchema.methods.getSafeJSON = function() {
    const obj = this.toObject();
    const { path, ip, __v, ...safe } = obj;
    return safe;
};

// === 导出模型 ===
module.exports = mongoose.model('Video', videoSchema);